<!DOCTYPE html>
<html lang="zh">

<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
	<meta name="keywords" content="dromara.org" />
	<meta name="description" content="dromara.org" />
	<!-- 网页标签标题 -->
	<title>dromara(Open source organization)</title>
	<link rel="shortcut icon" href="/website/img/docsite.ico"/>
	<link rel="stylesheet" href="/website/build/documentation.css" />
</head>
<body>
	<div id="root"><div class="documentation-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/website/en-us/index.html"><img class="logo" src="/website/img/dromara.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">中</span><div class="header-menu"><img class="header-menu-toggle" src="/website/img/system/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a href="/website/en-us/index.html" target="_self">Home</a><div class="sub-menu"><ul></ul></div></li><li class="menu-item menu-item-normal menu-item-normal-active"><a href="#">Document</a><div class="sub-menu"><ul><li><a href="/website/en-us/docs/soul/soul.html" target="_self">Soul</a></li><li><a href="/website/en-us/docs/hmily/index.html" target="_self">Hmily</a></li></ul></div></li><li class="menu-item menu-item-normal"><a href="/website/en-us/blog/index.html" target="_self">Blog</a><div class="sub-menu"><ul></ul></div></li><li class="menu-item menu-item-normal"><a href="/website/en-us/community/index.html" target="_self">Community</a><div class="sub-menu"><ul></ul></div></li></ul></div></div></header><section class="content-section"><div class="sidemenu" id="menu"><div class="sidemenu-toggle"><img src="https://img.alicdn.com/tfs/TB1E6apXHGYBuNjy0FoXXciBFXa-200-200.png"/></div><ul><li class="menu-item menu-item-level-1"><span>Soul</span><ul><li style="height:36px;overflow:hidden" class="menu-item menu-item-level-2"><a href="/website/en-us/docs/soul/soul.html" target="_self">Home  </a></li><li style="height:36px;overflow:hidden" class="menu-item menu-item-level-2"><a href="/website/en-us/docs/soul/team.html" target="_self">Team</a></li><li style="height:36px;overflow:hidden" class="menu-item menu-item-level-2"><a href="/website/en-us/docs/soul/db.html" target="_self">Database Design</a></li><li style="height:36px;overflow:hidden" class="menu-item menu-item-level-2"><a href="/website/en-us/docs/soul/config.html" target="_self">Config</a></li><li style="height:36px;overflow:hidden" class="menu-item menu-item-level-2"><a href="/website/en-us/docs/soul/dataSync.html" target="_self">DataSync</a></li><li style="height:36px;overflow:hidden" class="menu-item menu-item-level-2"><a href="/website/en-us/docs/soul/metaData.html" target="_self">MetaData</a></li><li style="height:792px;overflow:hidden" class="menu-item menu-item-level-2"><span>User Document<img style="transform:rotate(0deg)" class="menu-toggle" src="/website/img/system/arrow_down.png"/></span><ul><li class="menu-item menu-item-level-3"><a href="/website/en-us/docs/soul/setup.html" target="_self">Set up</a></li><li class="menu-item menu-item-level-3"><a href="/website/en-us/docs/soul/soul-dict.html" target="_self">Dictionary management</a></li><li class="menu-item menu-item-level-3"><a href="/website/en-us/docs/soul/plugin-handle.html" target="_self">Plugin handle explanation</a></li><li class="menu-item menu-item-level-3"><a href="/website/en-us/docs/soul/user-http.html" target="_self">Http proxy</a></li><li class="menu-item menu-item-level-3"><a href="/website/en-us/docs/soul/user-dubbo.html" target="_self">Dubbo proxy</a></li><li class="menu-item menu-item-level-3"><a href="/website/en-us/docs/soul/user-springcloud.html" target="_self">Spring cloud proxy</a></li><li class="menu-item menu-item-level-3"><a href="/website/en-us/docs/soul/user-sofa.html" target="_self">Sofa rpc proxy</a></li><li class="menu-item menu-item-level-3"><a href="/website/en-us/docs/soul/selector.html" target="_self">Selector and Rule</a></li><li class="menu-item menu-item-level-3"><a href="/website/en-us/docs/soul/user-dataSync.html" target="_self">Use data sync</a></li><li class="menu-item menu-item-level-3"><a href="/website/en-us/docs/soul/plugin-divide.html" target="_self">Divide Plugin</a></li><li class="menu-item menu-item-level-3"><a href="/website/en-us/docs/soul/plugin-dubbo.html" target="_self">Dubbo plugin</a></li><li class="menu-item menu-item-level-3"><a href="/website/en-us/docs/soul/plugin-springcloud.html" target="_self">Spring cloud plugin</a></li><li class="menu-item menu-item-level-3"><a href="/website/en-us/docs/soul/plugin-sofa.html" target="_self">Sofa plugin</a></li><li class="menu-item menu-item-level-3"><a href="/website/en-us/docs/soul/plugin-rateLimiter.html" target="_self">RateLimiter plugin</a></li><li class="menu-item menu-item-level-3"><a href="/website/en-us/docs/soul/plugin-hystrix.html" target="_self">Hystrix plugin</a></li><li class="menu-item menu-item-level-3"><a href="/website/en-us/docs/soul/plugin-sentinel.html" target="_self">Sentinel plugin</a></li><li class="menu-item menu-item-level-3"><a href="/website/en-us/docs/soul/plugin-monitor.html" target="_self">Monitor plugin</a></li><li class="menu-item menu-item-level-3"><a href="/website/en-us/docs/soul/plugin-waf.html" target="_self">Waf plugin</a></li><li class="menu-item menu-item-level-3"><a href="/website/en-us/docs/soul/plugin-sign.html" target="_self">Sign plugin</a></li><li class="menu-item menu-item-level-3"><a href="/website/en-us/docs/soul/plugin-rewrite.html" target="_self">Rewrite plugin</a></li><li class="menu-item menu-item-level-3"><a href="/website/en-us/docs/soul/plugin-websocket.html" target="_self">Websocket plugin</a></li></ul></li><li style="height:360px;overflow:hidden" class="menu-item menu-item-level-2"><span>Developer Guide<img style="transform:rotate(0deg)" class="menu-toggle" src="/website/img/system/arrow_down.png"/></span><ul><li class="menu-item menu-item-level-3"><a href="/website/en-us/docs/soul/dev-filter.html" target="_self">Custom filter </a></li><li class="menu-item menu-item-level-3"><a href="/website/en-us/docs/soul/dev-plugin.html" target="_self">Custom plugin</a></li><li class="menu-item menu-item-level-3"><a href="/website/en-us/docs/soul/dev-file.html" target="_self">File and Image</a></li><li class="menu-item menu-item-level-3"><a href="/website/en-us/docs/soul/dev-iphost.html" target="_self">Custom parsing IP and Host</a></li><li class="menu-item menu-item-level-3"><a href="/website/en-us/docs/soul/dev-result.html" target="_self">Custom result</a></li><li class="menu-item menu-item-level-3"><a href="/website/en-us/docs/soul/dev-sign.html" target="_self">Custom sign algorithm</a></li><li class="menu-item menu-item-level-3"><a href="/website/en-us/docs/soul/dev-client.html" target="_self">Developer soul client</a></li><li class="menu-item menu-item-level-3"><a href="/website/en-us/docs/soul/dev-thread.html" target="_self">Thread</a></li><li class="menu-item menu-item-level-3"><a href="/website/en-us/docs/soul/dev-netty.html" target="_self">Soul optimize</a></li></ul></li><li style="height:144px;overflow:hidden" class="menu-item menu-item-level-2"><span>Community<img style="transform:rotate(0deg)" class="menu-toggle" src="/website/img/system/arrow_down.png"/></span><ul><li class="menu-item menu-item-level-3"><a href="/website/en-us/docs/soul/contributor.html" target="_self">Contributor</a></li><li class="menu-item menu-item-level-3"><a href="/website/en-us/docs/soul/committer.html" target="_self">Committer</a></li><li class="menu-item menu-item-level-3"><a href="/website/en-us/docs/soul/code-conduct.html" target="_self">Code conduct</a></li></ul></li></ul></li></ul></div><div class="doc-content markdown-body" id="doc-body"><h2>Explanation</h2>
<ul>
<li>Sign is a native plugin of soul Gateway and is used to process signature authentication of requests.</li>
</ul>
<h2>Plugin Setting</h2>
<ul>
<li>In <code>soul-admin</code> -&gt; plugin management --&gt; <code>sign</code> set to enable.</li>
</ul>
<h2>Plugin Usage</h2>
<ul>
<li>Introducing <code>sign</code> dependency in the pom.xml file of the gateway</li>
</ul>
<pre><code class="language-xml">  <span class="hljs-comment">&lt;!-- soul sign plugin start--&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.dromara<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>soul-spring-boot-starter-plugin-sign<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
     <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>${last.version}<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>
  <span class="hljs-comment">&lt;!-- soul sign plugin end--&gt;</span>
</code></pre>
<ul>
<li>
<p>Selectors and rules, please refer to: <a href="docs/en-us/soul/selector.md">selector</a>。</p>
<ul>
<li>Only those matched requests can be authenticated by signature.</li>
</ul>
</li>
</ul>
<h2>Add AK/SK</h2>
<ul>
<li>In soul-admin --&gt; In authentication management, click <code>Add</code> to add a new AK/SK。</li>
</ul>
<h2>Implementation of Gateway Technology</h2>
<ul>
<li>Adopt Ak/SK authentication technical scheme.</li>
<li>Adopt authentication plug-in and Chain of Responsibility Pattern to realize.</li>
<li>Take effect when the authentication plugin is enabled and all interfaces are configured for authentication.</li>
</ul>
<h2>Authentication Guide</h2>
<ul>
<li>
<p>Step 1: AK/SK is assigned by the gateway. For example, the AK assigned to you is: <code>1test123456781</code> SK is: ` 506eeb535cf740d7a755cb49f4a1536'</p>
</li>
<li>
<p>Step 2: Decide the gateway path you want to access, such as ` /api/service/abc'</p>
</li>
<li>
<p>Step 3: Construct parameters (the following are general parameters)</p>
</li>
</ul>
<table>
<thead>
<tr>
<th>Field</th>
<th style="text-align:right">Value</th>
<th style="text-align:center">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>timestamp</td>
<td style="text-align:right">current timestamp(String)</td>
<td style="text-align:center">The number of milliseconds of the current time（gateway will filter requests the before 5 minutes）</td>
</tr>
<tr>
<td>path</td>
<td style="text-align:right">/api/service/abc</td>
<td style="text-align:center">The path that you want to request(Modify by yourself according to your configuration of gateway)</td>
</tr>
<tr>
<td>version</td>
<td style="text-align:right">1.0.0</td>
<td style="text-align:center"><code>1.0.0</code> is a fixed value ，String</td>
</tr>
</tbody>
</table>
<p>Sort the above two field natually according to the key, then splice fields and fields, finally splice SK. The following is a code example.</p>
<p>Step 1: First, construct a Map.</p>
<pre><code class="language-java">
   Map&lt;String, String&gt; map = Maps.newHashMapWithExpectedSize(<span class="hljs-number">2</span>);
   <span class="hljs-comment">//timestamp is string format of millisecond. String.valueOf(LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli()) </span>
   map.put(<span class="hljs-string">"timestamp"</span>,<span class="hljs-string">"1571711067186"</span>);  <span class="hljs-comment">// Value should be string format of milliseconds</span>
   map.put(<span class="hljs-string">"path"</span>, <span class="hljs-string">"/api/service/abc"</span>);
   map.put(<span class="hljs-string">"version"</span>, <span class="hljs-string">"1.0.0"</span>);
</code></pre>
<p>Step 2: Sort the Keys naturally, then splice the key and values, and finally splice the SK assigned to you.</p>
<pre><code class="language-java">List&lt;String&gt; storedKeys = Arrays.stream(map.keySet()
                .toArray(<span class="hljs-keyword">new</span> String[]{}))
                .sorted(Comparator.naturalOrder())
                .collect(Collectors.toList());
<span class="hljs-keyword">final</span> String sign = storedKeys.stream()
                .map(key -&gt; String.join(<span class="hljs-string">""</span>, key, params.get(key)))
                .collect(Collectors.joining()).trim()
                .concat(<span class="hljs-string">"506EEB535CF740D7A755CB4B9F4A1536"</span>);
</code></pre>
<ul>
<li>The returned sign value should be:path/api/service/abctimestamp1571711067186version1.0.0506EEB535CF740D7A755CB4B9F4A1536</li>
</ul>
<p>Step 3: Md5 encryption and then capitalization.</p>
<pre><code class="language-java">DigestUtils.md5DigestAsHex(sign.getBytes()).toUpperCase()
</code></pre>
<ul>
<li>The final returned value is:A021BF82BE342668B78CD9ADE593D683</li>
</ul>
<h2>Request GateWay</h2>
<ul>
<li>
<p>If your visited path is:/api/service/abc。</p>
</li>
<li>
<p>Address: http: domain name of gateway /api/service/abc.</p>
</li>
<li>
<p>Set <code>header</code>，<code>header</code> Parameter：</p>
</li>
</ul>
<table>
<thead>
<tr>
<th>Field</th>
<th style="text-align:right">Value</th>
<th style="text-align:center">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>timestamp</td>
<td style="text-align:right"><code>1571711067186</code></td>
<td style="text-align:center">Timestamp when signing</td>
</tr>
<tr>
<td>appKey</td>
<td style="text-align:right"><code>1TEST123456781</code></td>
<td style="text-align:center">The AK value assigned to you</td>
</tr>
<tr>
<td>sign</td>
<td style="text-align:right"><code>A90E66763793BDBC817CF3B52AAAC041</code></td>
<td style="text-align:center">The signature obtained above</td>
</tr>
<tr>
<td>version</td>
<td style="text-align:right"><code>1.0.0</code></td>
<td style="text-align:center"><code>1.0.0</code> is a fixed value.</td>
</tr>
</tbody>
</table>
<ul>
<li>The signature plugin will filter requests after 5 minutes by default</li>
</ul>
<h2>If the authentication fails, will return code 401, message may change.</h2>
<pre><code class="language-json">"code":401,"message":"sign is not pass,Please check you sign algorithm!","data":null}
</code></pre>
<h2>Extension of Signature Authentication Algorithm</h2>
<ul>
<li>Please refer to: <a href="docs/en-us/soul/dev-sign.md">dev-sign</a>.</li>
</ul>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/website/img/dromara.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Any unit or individual reprint all relevant information of this website, please indicate the source.</p></div><div class="col col-6"><dl><dt>Document</dt><dd><a href="/website/en-us/docs/soul/soul.html" target="_self">Overview </a></dd><dd><a href="/website/en-us/docs/soul/soul.html" target="_self">Stat up</a></dd><dd><a href="/website/en-us/docs/soul/soul.html" target="_self">Developer Guide</a></dd></dl></div><div class="col col-6"><dl><dt>Resource</dt><dd><a href="/website/en-us/blog/index.html" target="_self">Blog</a></dd><dd><a href="/website/en-us/community/index.html" target="_self">Community</a></dd></dl></div></div><div class="copyright"><span>Copyright ©2020 xiaoyu@apache.org by xiaoyu</span></div></div></footer></div></div>
	<script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
	<script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
	<script>
		window.rootPath = '/website';
  </script>
	<script src="/website/build/documentation.js"></script>
</body>
</html>